﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
namespace DTN.Core.Common
{
    public class BadWordFilter
    {
        public enum CleanUpOptions
        {
            ReplaceEachWord,
            BlankBadText,
            ReplaceWholeText
        }

        private BadWordFilter()
        {
            patterns = new List<Regex>();
        }

        /// <summary>
        /// The patterns
        /// </summary>
        private List<Regex> patterns;


        public List<Regex> Patterns
        {
            get { return patterns; }
            set { patterns = value; }
        }

        private static BadWordFilter m_instance = null;

        public static BadWordFilter Instance
        {
            get
            {
                if (m_instance == null)
                    m_instance = CreateBadWordFilter(HttpContext.Current.Server.MapPath("/ListofBadWords.txt"));
                if (m_instance != null && m_instance.Patterns != null && m_instance.Patterns.Count <= 0)
                    m_instance = CreateBadWordFilter(HttpContext.Current.Server.MapPath("/ListofBadWords.txt"));
                return m_instance;
            }
        }
        public static void Clear()
        {
            m_instance = null;
        }
        /// <summary>
        /// Create all the patterns required and add them to the list
        /// </summary>
        /// <param name="badWordFile"></param>
        /// <returns></returns>
        protected static BadWordFilter CreateBadWordFilter(string badWordFile)
        {
            BadWordFilter filter = new BadWordFilter();
            //XmlDocument badWordDoc = new XmlDocument();
            //badWordDoc.Load(badWordFile);
            StreamReader reader = null;
            try
            {
                reader = new StreamReader(badWordFile);
                using (reader)
                {
                    try
                    {
                        //Loop through the txt document for each bad word in the list
                        while (!reader.EndOfStream)
                        {
                            //Split each word into a character array
                            //char[] characters = reader.ReadLine().ToCharArray();

                            //We need a fast way of appending to an exisiting string
                            StringBuilder patternBuilder = new StringBuilder();

                            //The start of the patterm
                            patternBuilder.Append("(\\b");
                            patternBuilder.Append(reader.ReadLine().Replace(" ", "\\s"));

                            //We next go through each letter and append the part of the pattern.
                            //It is this stage which generates the upper and lower case variations
                            //for (int j = 0; j < characters.Length; j++)
                            //{
                            //    if (characters[j].ToString().ToLower() == "é")
                            //        patternBuilder.AppendFormat("[{0}|{1}]", "\\U+00c9", "\\U+00e9");
                            //    else if (characters[j].ToString().ToLower() == "ì")
                            //        patternBuilder.AppendFormat("[{0}|{1}]", "\\U+00cc", "\\U+00ec");
                            //    else
                            //        patternBuilder.AppendFormat("[{0}|{1}]", characters[j].ToString().ToLower(), characters[j].ToString().ToUpper());

                            //     //patternBuilder.AppendFormat("[{0}|{1}][\\W]*", characters[j].ToString().ToLower(), characters[j].ToString().ToUpper());
                            //}

                            //End the pattern
                            patternBuilder.Append("\\b)");

                            //Add the new pattern to our list.
                            filter.Patterns.Add(new Regex(patternBuilder.ToString(),RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace));
                        }
                        if (reader != null) reader.Close();
                    }
                    catch (Exception ex)
                    {
                    }
                    finally
                    {
                        if (reader != null) reader.Close();
                    }
                }
            }
            catch (Exception ex)
            {
            }   
            finally
            {
                if (reader != null) reader.Close();
            }

            return filter;
        }

        public string GetCleanString(string input, CleanUpOptions options)
        {
            bool isBadString  = false;
            return GetCleanString(input, options, out isBadString);
        }

        /// <summary>
        /// The function which returns the manipulated string
        /// </summary>
        /// <param name="input"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        /// 
        public string GetCleanString(string input, CleanUpOptions options, out bool isBadString)
        {
          isBadString = false;
            try
            {
                if (!string.IsNullOrEmpty(input) && patterns != null)
                {
                    for (int i = 0; i < patterns.Count; i++)
                    {
                        if (patterns[i].Match(input).Success)
                        {
                            if (isBadString == false)
                                isBadString = true;
                            input = patterns[i].Replace(input, " *** ");
                        }
                    }

                     
                }
            }
            catch (Exception ex)
            {
            }
            return input;
        }
    }
}